package com.minelx.table.core;

import com.minelx.table.core.series.Series;
import com.minelx.table.core.series.index.Indexes;
import com.minelx.table.core.series.source.Source;

import java.util.stream.Stream;

public class InnerMergingTableProvider implements TableProvider {
	private final Indexes rowIndexes;

	private final Indexes columnIndexes;

	private final Intersections intersections;

	private final Series<String> title;

	public InnerMergingTableProvider(Table left, Table right, String leftOn, String rightOn) {
		// FIXME 2021/8/27  wait for me!!!
		intersections = new Intersections(left, right, leftOn, rightOn);

		rowIndexes = Indexes.range(0, intersections.length());
		columnIndexes = Indexes.range(0, left.width() + right.width());

		// FIXME 2021/10/12  wait for me!!!      use statistics instead of sequential
		title = Series.create(columnIndexes, Source.concat(
				left.form().title().sequential(),
				right.form().title().sequential()
		));
	}

	@Override
	public Series<String> row(long at) {
		// FIXME 2021/10/12  wait for me!!!
		return Series.create(columnIndexes, Source.concat(
				intersections.leftRowAt(at).sequential(),
				intersections.rightRowAt(at).sequential()
		));
	}

	@Override
	public Series<String> column(long columnAt) {
		return Series.create(rowIndexes, new ColumnSource(columnAt));
	}

	@Override
	public Series<String> title() {
		return title;
	}

	@Override
	public Indexes rowIndexes() {
		return rowIndexes;
	}

	@Override
	public Indexes columnIndexes() {
		return columnIndexes;
	}

	private class ColumnSource implements Source<String> {
		private final long columnAt;

		public ColumnSource(long columnAt) {
			this.columnAt = columnAt;
		}

		@Override
		public String at(long rowAt) {
			return row(rowAt).at(columnAt);
		}

		@Override
		public long len() {
			return rowIndexes.len();
		}

		@Override
		public Stream<String> stream() {
			return rowIndexes.stream()
					.mapToObj(rowAt -> row(rowAt).at(columnAt));
		}
	}
}
